home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / pathname.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  2.9 KB  |  121 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "dirutil.h"
  4.  
  5. static void near crunch __ARGS((char *buf,char *path));
  6.  
  7. /* Given a working directory and an arbitrary pathname, resolve them into
  8.  * an absolute pathname. Memory is allocated for the result, which
  9.  * the caller must free
  10.  */
  11. char *
  12. pathname(cd,path)
  13. char *cd;    /* Current working directory */
  14. char *path;    /* Pathname argument */
  15. {
  16.     char *buf;
  17. #ifdef    MSDOS
  18.     char *cp, *tbuf, c;
  19.     int tflag = 0;
  20. #endif
  21.  
  22.     if(cd == NULLCHAR || path == NULLCHAR)
  23.         return NULLCHAR;
  24.  
  25. #ifdef    MSDOS
  26.     /* If path has any backslashes, make a local copy with them
  27.      * translated into forward slashes
  28.      */
  29.     if(strchr(path,'\\') != NULLCHAR){
  30.         tflag = 1;
  31.         cp = tbuf = mxallocw(strlen(path));
  32.         while((c = *path++) != '\0'){
  33.             if(c == '\\')
  34.                 *cp++ = '/';
  35.             else
  36.                 *cp++ = c;
  37.         }
  38.         *cp = '\0';
  39.         path = tbuf;
  40.     }
  41. #endif
  42.  
  43.     /* Strip any leading white space on args */
  44.     while(*cd == ' ' || *cd == '\t')
  45.         cd++;
  46.     while(*path == ' ' || *path == '\t')
  47.         path++;
  48.  
  49.     /* Allocate and initialize output buffer; user must free */
  50.     buf = mxallocw(strlen(cd) + strlen(path) + 10);    /* fudge factor */
  51.     buf[0] = '\0';
  52.  
  53.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  54.     if(path[0] != '/')
  55.         crunch(buf,cd);
  56.  
  57.     crunch(buf,path);
  58.  
  59.     /* Special case: null final path means the root directory */
  60.     if(buf[0] == '\0'){
  61.         buf[0] = '/';
  62.         buf[1] = '\0';
  63.     }
  64. #ifdef MSDOS
  65.     if(tflag)
  66.         xfree(tbuf);
  67. #endif
  68.     if(buf[2] == ':') {
  69.         cp = strxdup(&buf[1]);
  70.         xfree(buf);
  71.         buf = cp;
  72.     }
  73.     return buf;
  74. }
  75.  
  76. /* Process a path name string, starting with and adding to
  77.  * the existing buffer
  78.  */
  79. static void near
  80. crunch(buf,path)
  81. char *buf;
  82. char *path;
  83. {
  84.     char *cp = buf + strlen(buf);    /* Start write at end of current buffer */
  85.  
  86.     /* Now start crunching the pathname argument */
  87.     for(;;){
  88.         /* Strip leading /'s; one will be written later */
  89.         while(*path == '/')
  90.             path++;
  91.         if(*path == '\0')
  92.             break;        /* no more, all done */
  93.         /* Look for parent directory references, either at the end
  94.          * of the path or imbedded in it
  95.          */
  96.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  97.             /* Hop up a level */
  98.             if((cp = strrchr(buf,'/')) == NULLCHAR)
  99.                 cp = buf;    /* Don't back up beyond root */
  100.             *cp = '\0';        /* In case there's another .. */
  101.             path += 2;        /* Skip ".." */
  102.             while(*path == '/')    /* Skip one or more slashes */
  103.                 path++;
  104.         /* Look for current directory references, either at the end
  105.          * of the path or imbedded in it
  106.          */
  107.         } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  108.             /* "no op" */
  109.             path++;            /* Skip "." */
  110.             while(*path == '/')    /* Skip one or more slashes */
  111.                 path++;
  112.         } else {
  113.             /* Ordinary name, copy up to next '/' or end of path */
  114.             *cp++ = '/';
  115.             while(*path != '/' && *path != '\0')
  116.                 *cp++ = *path++;
  117.         }
  118.     }
  119.     *cp++ = '\0';
  120. }
  121.